/*
 * #%L
 * Client
 * %%
 * Copyright (C) 2011 Ractoc.com
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.ractoc.opengamefinder.client.screens.controllers;

import org.apache.log4j.Logger;

import com.ractoc.opengamefinder.api.messages.ErrorMessage;
import com.ractoc.opengamefinder.api.results.MessageResultsErrorCodes;
import com.ractoc.opengamefinder.client.plugins.messages.DisplayScreenMessage;
import com.ractoc.opengamefinder.client.plugins.messages.GuiMessage;
import com.ractoc.opengamefinder.client.plugins.nifty.ScreenType;
import com.ractoc.opengamefinder.client.plugins.results.DisplayScreenMessageResult;
import com.ractoc.pffj.api.BasePluginMessageResult;
import com.ractoc.pffj.core.PluginController;
import com.ractoc.pffj.core.PluginException;

import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.screen.ScreenController;

/**
 * Basic screen controller class. Contains all the methods which are implemented
 * similarly in all the other screencontrollers.
 * 
 * @author ractoc
 * @version 0.1
 */
public abstract class BaseScreenController implements ScreenController {

    private static final String ERROR_PLUGIN_MESSAGE = "Error sending message through the plugin system";
    private static final String GUI_PLUGIN = "guiPlugin";
    private static Logger logger = Logger.getLogger(BaseScreenController.class.getName());
    private Nifty nifty;
    private Screen screen;
    
    /**
     * Sets the nifty instance for this screen.
     * 
     * @param niftyParam The nifty instance for this screen.
     */
    public final void setNifty(final Nifty niftyParam) {
        this.nifty = niftyParam;
    }

    /**
     * Returns the nifty instance for this screen.
     * 
     * @return The nifty instance for this screen.
     */
    public final Nifty getNifty() {
        return nifty;
    }

    /**
     * Sets the screen instance for this screen.
     * 
     * @param screenParam The screen instance for this screen.
     */
    public final void setScreen(final Screen screenParam) {
        this.screen = screenParam;
    }

    /**
     * Returns the screen instance for this screen.
     * 
     * @return The screen instance for this screen.
     */
    public final Screen getScreen() {
        return screen;
    }

    /**
     * Handles switching between screens.
     * 
     * @param screenParam The screen to switch to.
     * @param screenTypeParam The screen type to switch to.
     */
    protected final void displayScreen(final String screenParam, final ScreenType screenTypeParam) {
        BasePluginMessageResult result = new DisplayScreenMessageResult();
        try {
            final DisplayScreenMessage dsMsg = new DisplayScreenMessage();
            dsMsg.setScreenName(screenParam);
            final GuiMessage guiMsg = new GuiMessage();
            guiMsg.setPayload(dsMsg);
            guiMsg.setType(screenTypeParam);
            result = (DisplayScreenMessageResult) PluginController.getCurrentPluginController().processMessage(
                    GUI_PLUGIN, guiMsg);
        } catch (final PluginException e) {
            result.setErrorCode(MessageResultsErrorCodes.INTERNAL_ERROR);
            logger.error(ERROR_PLUGIN_MESSAGE, e);
        }
        if (result.getErrorCode() != MessageResultsErrorCodes.SUCCESS) {
            displayError(result.getErrorCode(), screenTypeParam);
        }
    }

    /**
     * Handles displaying an Error message on the screen.
     * 
     * @param errorCode The error code for which the message needs to be displayed.
     * @param screenType The ScreenType on which to display the error. This is
     *            typically the current screentype.
     */
    protected final void displayError(final Enum errorCode, final ScreenType screenType) {
        final ErrorMessage eMsg = new ErrorMessage();
        eMsg.setErrorCode(errorCode);
        final GuiMessage guiMsg = new GuiMessage();
        guiMsg.setPayload(eMsg);
        guiMsg.setType(screenType);
        try {
            PluginController.getCurrentPluginController().processMessage(GUI_PLUGIN, eMsg);
        } catch (final PluginException e) {
            logger.error(ERROR_PLUGIN_MESSAGE, e);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void bind(final Nifty newNiftyParam, final Screen newScreenParam) {
        this.setNifty(newNiftyParam);
        this.setScreen(newScreenParam);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onStartScreen() {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onEndScreen() {
    }
}
